#!/bin/sh

echo "###############################################################################" >/dev/null
echo "# Script Summary:                                                             #" >/dev/null
echo "# Author:                  yu.zuo                                             #" >/dev/null
echo "# Create Date:             2020.05.23                                         #" >/dev/null
echo "# Update Date:             2020.05.23                                         #" >/dev/null
echo "# Script version:          1.0.0                                              #" >/dev/null
echo "# Url: https://gitee.com/asteriskoschinazuo/c_library_build                   #" >/dev/null
echo "#                                                                             #" >/dev/null
echo "# Brief introduction:                                                         #" >/dev/null
echo "# Declare global variables                                                    #" >/dev/null
echo "#                                                                             #" >/dev/null
echo "# Prerequisites:                                                              #" >/dev/null
echo "# GNU bash (version 3.2.57 test success on macOS)                             #" >/dev/null
echo "#                                                                             #" >/dev/null
echo "# Reference:                                                                  #" >/dev/null
echo "# none.                                                                       #" >/dev/null
echo "###############################################################################" >/dev/null

function log() {
    echo "$@" >>$logfile
}

function die() {
    log "$@"
    echo "$error_color$bold_color$@$reset_color"
    exit 1
}

function toupper() {
    echo "$@" | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
}

function tolower() {
    echo "$@" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
}

function c_escape() {
    echo "$*" | sed 's/["\\]/\\\0/g'
}

function sh_quote() {
    v=$(echo "$1" | sed "s/'/'\\\\''/g")
    test "x$v" = "x${v#*[!A-Za-z0-9_/.+-]}" || v="'$v'"
    echo "$v"
}

function cleanws() {
    echo "$@" | sed 's/^ *//;s/[[:space:]][[:space:]]*/ /g;s/ *$//'
}

function filter() {
    pat=$1
    shift
    for v; do
        eval "case '$v' in $pat) printf '%s ' '$v' ;; esac"
    done
}

function filter_out() {
    pat=$1
    shift
    for v; do
        eval "case '$v' in $pat) ;; *) printf '%s ' '$v' ;; esac"
    done
}

function map() {
    m=$1
    shift
    for v; do eval $m; done
}

function add_suffix() {
    suffix=$1
    shift
    for v; do echo ${v}${suffix}; done
}

function remove_suffix() {
    suffix=$1
    shift
    for v; do echo ${v%$suffix}; done
}

function set_all() {
    value=$1
    shift
    for var in $*; do
        eval $var=$value
    done
}

function set_weak() {
    value=$1
    shift
    for var; do
        eval : \${$var:=$value}
    done
}

function sanitize_var_name() {
    echo $@ | sed 's/[^A-Za-z0-9_]/_/g'
}

function pushvar() {
    for pvar in $*; do
        eval level=\${${pvar}_level:=0}
        eval ${pvar}_${level}="\$$pvar"
        eval ${pvar}_level=$(($level + 1))
    done
}

function popvar() {
    for pvar in $*; do
        eval level=\${${pvar}_level:-0}
        test $level = 0 && continue
        eval level=$(($level - 1))
        eval $pvar="\${${pvar}_${level}}"
        eval ${pvar}_level=$level
        eval unset ${pvar}_${level}
    done
}
function request() {
    for var in $*; do
        eval ${var}_requested=yes
        eval $var=
    done
}

function enable() {
    set_all yes $*
}

function disable() {
    set_all no $*
}

function disable_with_reason() {
    disable $1
    eval "${1}_disable_reason=\"$2\""
    if requested $1; then
        die "ERROR: $1 requested, but $2"
    fi
}

function enable_weak() {
    set_weak yes $*
}

function disable_weak() {
    set_weak no $*
}

function enable_sanitized() {
    for var; do
        enable $(sanitize_var_name $var)
    done
}

function disable_sanitized() {
    for var; do
        disable $(sanitize_var_name $var)
    done
}

function do_enable_deep() {
    for var; do
        enabled $var && continue
        set -- $var
        eval enable_deep \$${var}_select
        var=$1
        eval enable_deep_weak \$${var}_suggest
    done
}

function enable_deep() {
    do_enable_deep $*
    enable $*
}

function enable_deep_weak() {
    for var; do
        disabled $var && continue
        set -- $var
        do_enable_deep $var
        var=$1
        enable_weak $var
    done
}

function requested() {
    test "${1#!}" = "$1" && op="=" || op="!="
    eval test "x\$${1#!}_requested" $op "xyes"
}

function enabled() {
    test "${1#!}" = "$1" && op="=" || op="!="
    eval test "x\$${1#!}" $op "xyes"
}

function disabled() {
    test "${1#!}" = "$1" && op="=" || op="!="
    eval test "x\$${1#!}" $op "xno"
}

function enabled_all() {
    for opt; do
        enabled $opt || return 1
    done
}

function disabled_all() {
    for opt; do
        disabled $opt || return 1
    done
}

function enabled_any() {
    for opt; do
        enabled $opt && return 0
    done
}

function disabled_any() {
    for opt; do
        disabled $opt && return 0
    done
    return 1
}

function set_default() {
    for opt; do
        eval : \${$opt:=\$${opt}_default}
    done
}

function is_in() {
    value=$1
    shift
    for var in $*; do
        [ $var = $value ] && return 0
    done
    return 1
}

function append() {
    var=$1
    shift
    eval "$var=\"\$$var $*\""
}

function prepend() {
    var=$1
    shift
    eval "$var=\"$* \$$var\""
}

function reverse() {
    eval '
        reverse_out=
        for v in $'$1'; do
            reverse_out="$v $reverse_out"
        done
        '$1'=$reverse_out
    '
}

# keeps the last occurence of each non-unique item
function unique() {
    unique_out=
    eval unique_in=\$$1
    reverse unique_in
    for v in $unique_in; do
        # " $unique_out" +space such that every item is surrounded with spaces
        case " $unique_out" in *" $v "*) continue ;; esac # already in list
        unique_out="$unique_out$v "
    done
    reverse unique_out
    eval $1=\$unique_out
}

function resolve() {
    resolve_out=
    eval resolve_in=\$$1
    for v in $resolve_in; do
        eval 'resolve_out="$resolve_out$'$v' "'
    done
    eval $1=\$resolve_out
}

function add_cppflags() {
    append CPPFLAGS "$@"
}

function add_cflags() {
    append CFLAGS $($cflags_filter "$@")
}

function add_cflags_headers() {
    append CFLAGS_HEADERS $($cflags_filter "$@")
}

function add_cxxflags() {
    append CXXFLAGS $($cflags_filter "$@")
}

function add_objcflags() {
    append OBJCFLAGS $($objcflags_filter "$@")
}

function add_asflags() {
    append ASFLAGS $($asflags_filter "$@")
}

function add_ldflags() {
    append LDFLAGS $($ldflags_filter "$@")
}

function add_ldexeflags() {
    append LDEXEFLAGS $($ldflags_filter "$@")
}

function add_ldsoflags() {
    append LDSOFLAGS $($ldflags_filter "$@")
}

function add_extralibs() {
    prepend extralibs $($ldflags_filter "$@")
}

function add_stripflags() {
    append ASMSTRIPFLAGS "$@"
}

function add_host_cppflags() {
    append host_cppflags "$@"
}

function add_host_cflags() {
    append host_cflags $($host_cflags_filter "$@")
}

function add_host_ldflags() {
    append host_ldflags $($host_ldflags_filter "$@")
}
function test_cmd() {
    log "$@"
    "$@" >>$logfile 2>&1
}

function test_stat() {
    log test_stat "$@"
    stat "$1" >>$logfile 2>&1
}
